From e595e877624712b0838c510a827dec08621c9ade Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 19 May 2015 23:04:47 -0700 Subject: [PATCH] Optimize the number of calls to fs::metadata When iterating over `DirEntry` values the file type of the entry can typically be determined without a syscall, so use the new unstable APIs in `std::fs` to avoid an extra call to `fs::metadata`. When traversing large directory trees the improvement is quite noticeable! --- src/cargo/lib.rs | 2 +- src/cargo/ops/cargo_read_manifest.rs | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index d2b01e92c..3a47f1eac 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -1,5 +1,5 @@ #![deny(unused)] -#![feature(metadata_ext)] +#![feature(metadata_ext, file_type, dir_entry_ext)] #![cfg_attr(test, deny(warnings))] #[cfg(test)] extern crate hamcrest; diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs index 2ac4e0021..c765e02c9 100644 --- a/src/cargo/ops/cargo_read_manifest.rs +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -73,13 +73,8 @@ pub fn read_packages(path: &Path, source_id: &SourceId, config: &Config) } } -fn walk(path: &Path, callback: &mut F) -> CargoResult<()> - where F: FnMut(&Path) -> CargoResult -{ - if !fs::metadata(&path).map(|m| m.is_dir()).unwrap_or(false) { - return Ok(()) - } - +fn walk(path: &Path, callback: &mut FnMut(&Path) -> CargoResult) + -> CargoResult<()> { if !try!(callback(path)) { trace!("not processing {}", path.display()); return Ok(()) @@ -95,8 +90,10 @@ fn walk(path: &Path, callback: &mut F) -> CargoResult<()> Err(e) => return Err(From::from(e)), }; for dir in dirs { - let dir = try!(dir).path(); - try!(walk(&dir, callback)); + let dir = try!(dir); + if try!(dir.file_type()).is_dir() { + try!(walk(&dir.path(), callback)); + } } Ok(()) } -- 2.30.2